#include "internal.h"
#include "TemperatureSensor.h"
#include "TemperatureSensor.tmh"
#include "SensorBase.h" 

const PROPERTYKEY g_SupportedTemperatureProperties[] =
{
    SENSOR_PROPERTY_TYPE,
    SENSOR_PROPERTY_STATE,
    SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
    SENSOR_PROPERTY_MIN_REPORT_INTERVAL,
    SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
    SENSOR_PROPERTY_MANUFACTURER, 
    SENSOR_PROPERTY_MODEL,
    SENSOR_PROPERTY_SERIAL_NUMBER,
    SENSOR_PROPERTY_FRIENDLY_NAME,
    SENSOR_PROPERTY_DESCRIPTION, 
    SENSOR_PROPERTY_CONNECTION_TYPE,
    WPD_FUNCTIONAL_OBJECT_CATEGORY,
};

//TODO: why it doesn't use the platform fields ???

// {9D44A689-D13B-47b9-91E8-6315254DFAE6}
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_TEMPERATURE_FARENHEIT,  0x9d44a689, 0xd13b, 0x47b9, 0x91, 0xe8, 0x63, 0x15, 0x25, 0x4d, 0xfa, 0xe6, 2); //[VT_FILETIME]

// {EC636BCA-DB22-434b-92CC-B00E8C847DF9}
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_HUMIDITY_RELATIVE,  0xec636bca, 0xdb22, 0x434b, 0x92, 0xcc, 0xb0, 0xe, 0x8c, 0x84, 0x7d, 0xf9, 2); //[VT_FILETIME]

const PROPERTYKEY g_SupportedTemperatureDataFields[] =
{
    SENSOR_DATA_TYPE_TIMESTAMP,
    SENSOR_DATA_TYPE_HUMIDITY_RELATIVE,
    SENSOR_DATA_TYPE_TEMPERATURE_FARENHEIT,
};


/**
 *  This method is called to populate common PROPERTYKEYs found on temperature sensor objects.
 *
 *  The parameters sent to us are:
 *  pKeys - An IPortableDeviceKeyCollection to be populated with PROPERTYKEYs
 *
 *  The driver should:
 *  Add PROPERTYKEYs pertaining to the temperature sensor objects.
 */
VOID TemperatureSensor::AddPropertyKeys(
	IPortableDeviceKeyCollection* pKeys)
{
    if (pKeys != NULL)
    {
        for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedTemperatureProperties); dwIndex++)
        {
            pKeys->Add(g_SupportedTemperatureProperties[dwIndex] );
        }
    }
}

VOID TemperatureSensor::AddDataFieldKeys(
	IPortableDeviceKeyCollection* pKeys)
{
    if (pKeys != NULL)
    {
        for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedTemperatureDataFields); dwIndex++)
        {
            pKeys->Add(g_SupportedTemperatureDataFields[dwIndex] );
        }
    }
}

TemperatureSensor::TemperatureSensor(WpdObjectProperties* pWpdObjectProperties): 
	SensorBase(pWpdObjectProperties) 
{
	m_strSensorName		= SENSOR_TEMPERATURE_FRIENDLY_NAME;
	m_strSensorId		= SENSOR_TEMPERATURE_ID;
	m_gdSensorUniqueId	= SENSOR_TEMPERATURE_GUID;
	m_gdSensorCategory	= SENSOR_CATEGORY_ENVIRONMENTAL;
	m_gdSensorType		= SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE;
}

/// 
/// RetrieveTemp returns the temperature from a 
/// 64-bit sensor reading. The reading has the following
/// format: 2170724282 where the first byte is the identifier
/// the and third bytes contain packet length and the 
/// remaining bytes contain temperature in degrees farenheit
/// followed by the relative humidity. ("0724" is 72.4 degrees F
/// and "282" is 28.2 relative humidity).
///
float RetrieveTemp(__int64 llVal)
{
    __int64 llTemp=0;
    float fTemp=0.0;

    llTemp = llVal - 2170000000;
    llTemp = llTemp/1000;
    fTemp = (float)llTemp;
    fTemp = fTemp/10;
    return fTemp;
}

/// 
/// RetrieveHumidity returns the humidity from a 
/// 64-bit sensor reading. The reading has the following
/// format: 2170724282 where the first byte is the identifier
/// the and third bytes contain packet length and the 
/// remaining bytes contain temperature in degrees farenheit
/// followed by the relative humidity. ("0724" is 72.4 degrees F
/// and "282" is 28.2 relative humidity).
///
float RetrieveHumidity(__int64 llVal, float fTemp)
{
    __int64 llHumidity=0;
    float fHumidity=0.0;
    float fRemove = fTemp*10;
    fRemove = fRemove * 1000;

    llHumidity = llVal - 2170000000;
    llHumidity = llHumidity;
    fHumidity = (float)llHumidity;
    fHumidity = (fHumidity - fRemove)/10;

    return fHumidity;
}

HRESULT TemperatureSensor::OnGetDataValues(PROPERTYKEY &Key, IPortableDeviceValues *pValues)
{
	float fTemp		= 0.0;
    float fHumidity = 0.0;

	HRESULT hr = S_OK;

	// Set temperature sensor data
	if (IsEqualPropertyKey(Key, SENSOR_DATA_TYPE_HUMIDITY_RELATIVE))
	{
		fTemp = RetrieveTemp((__int64)m_llSensorReading);
		fHumidity = RetrieveHumidity((__int64)m_llSensorReading, fTemp);
		hr = pValues->SetFloatValue(SENSOR_DATA_TYPE_HUMIDITY_RELATIVE, fHumidity);
	}
	else if (IsEqualPropertyKey(Key, SENSOR_DATA_TYPE_TEMPERATURE_FARENHEIT))
	{
		fTemp = RetrieveTemp((__int64)m_llSensorReading);
		hr = pValues->SetFloatValue(SENSOR_DATA_TYPE_TEMPERATURE_FARENHEIT, fTemp);
	}
	else 
	{
		// call base method
		hr = SensorBase::OnGetDataValues(Key, pValues);
	}
	return hr;
}

